#!/bin/bash
#@Name: twitpic-gx
#@Author: Colin Dean <cad@cad.cx>
#@URL: http://cad.cx/twitter
#
# Usage: Use it from the CLI with 'twitpic image.jpg ["message"]'. 
#          Note the quotes! You /must/ use quotes on the CLI.
#        Use it from the GUI by right clicking on an image, go to "Open With"
#          and using a custom command pointed to wherever this script is.
#
#CHANGE THESE
USERNAME=YOUR-TWITTER-NICK
PASSWORD=YOUR-TWITTER-PASSWORD
#PATHS
ZENITY=/usr/bin/zenity
CURL=/usr/bin/curl
ICON=/usr/share/pixmaps/gnome-irc.png
CURLOPTS="-s" #make it always silent
#can someone suggest a better icon?
#STRINGS--someone want to localize?
WHAT="What are you doing? "
SORRY="Sorry, that was too long."
UPDATED="Twip submitted:"
FAILED="Twip failed. Check output for why."
CURL_MISSING="curl was not found at ${CURL}. Please install curl."
ZENITY_MISSING="zenity was not found at ${ZENITY}. Please install zenity."
#-------Woe to those who make changes below unless they know what it does------#
#META
NAME="twitpic-gx"
VERSION="1.0"
URL="http://cad.cx/twitter/twitter.xml"
#functions galore
function check_for_deps {
#I'm not going to bother checking for awk. Does any sane distro omit it?
  if [ ! -x ${CURL} ]; then 
    CURL=`which curl`
    if [ "$?" = 1 ]; then
      warn_user "${CURL_MISSING}"
      exit 1
    fi
  fi
  if [ ${TERM} != "xterm" -a ! -x ${ZENITY} ]; then 
    ZENITY=`which zenity`
    if [ "$?" = 1 ]; then
      warn_user "${ZENITY_MISSING}"
      exit 1
    fi
  fi
  CURL="${CURL} ${CURLOPTS}"
}

function getinput {
  if [ ${TERM} = "xterm" ]; then echo -n "${WHAT}"; read TWEET
    else TWEET=$(${ZENITY} --entry --text="${WHAT}" --entry-text="${1}")
  fi
}

function check_length {
  TWEETLENGTH=$(echo -n "${TWEET}" | wc -m)
  if [ ${TWEETLENGTH} -gt 110 ]; then
    warn_user "${SORRY} (${TWEETLENGTH} > 110)"
    getinput "${TWEET}"
    check_length
  fi
}

function warn_user {
  if [ ${TERM} = "xterm" ]; then echo "${1}"
    else ${ZENITY} --warning --text="${1}"
  fi
}

function urlencode () {
#one day, I will understand awk
#got this from somewhere
  echo "$@" | awk '
  BEGIN {
   # with inspiration from Heiner Steven and Rick Richardson
      split ("1 2 3 4 5 6 7 8 9 A B C D E F", hexit, " ")
      hexit [0] = 0 # setup the hex values we will use..
      for (i = 1 ; i <= 255 ; ++i) ord[ sprintf ("%c", i) "" ] = i + 0
    } {
      encoded = ""
      for (i = 1 ; i <= length ($0) ; ++i) {
        c = substr ($0, i, 1)
        if ( c ~ /[a-zA-Z0-9.-]/ ) { # allow only basic chrs
          encoded = encoded c
        } else { # encode everything else..
          lo = ord[c] % 16
          hi = int (ord[c] / 16);
          encoded = encoded "%" hexit [hi] hexit [lo]
        }
      }
#printf encoded
    }
  END {
    printf ("%s", encoded)
  }
'
}

function submit_tweet {
  OUTFILE="/tmp/twitpic_response-`date +%Y%m%d%H%M%S`.txt"
  ${CURL} \
       -F username=${USERNAME} \
       -F password=${PASSWORD} \
       -o ${OUTFILE} \
       -F message="${TWEET}" \
       -F source=twittergx \
       -F "media=@${MEDIA}" \
       -H "X-Twitter-Client: ${NAME}" \
       -H "X-Twitter-Client-Version: ${VERSION}" \
       -H "X-Twitter-Client-URL: ${URL}" \
       http://twitpic.com/api/uploadAndPost 
}

function notify_user {
  if [ "${1}" = "success" ]; then 
    TERM_MESSAGE="${UPDATED} ${TWEET}"
    GUI_MESSAGE="${UPDATED}\n\n${TWEET}"
    ICON_STR="--window-icon=${ICON}"
  fi
  if [ "${1}" = "failed" ]; then
    TERM_MESSAGE="${FAILED}"
    GUI_MESSAGE="${FAILED}"
    ICON_STR=""
  fi

  if [ ${TERM} = "xterm" ]; then echo "${TERM_MESSAGE}"
    else 
      exec 3> >(${ZENITY} --notification --listen ${ICON_STR})
      echo "message: ${GUI_MESSAGE}" >&3
      sleep 10
      exec 3>&-
  fi
   
}

function shrink_url {
#this only handles one URL!
  TWEETURL=`echo "${TWEET}" | grep -o http://[^[:space:]]*`
  TWEETURLLENGTH=`echo "${TWEETURL}" | wc -m`

  if [ ${TWEETURLLENGTH} -gt 23 ]; then
echo "Should only be in here if this is greater than 23: ${TWEETURLLENGTH}"
    #get the shrunken url
    SHRUNK=`${CURL} http://tweetburner.com/links \
                    -d link[url]="$(urlencode "${TWEETURL}")"`
    #replace the old url with the shrunken one
    TWEET=`echo "${TWEET}" | sed -e "s|${TWEETURL}|${SHRUNK}|g"`
  fi
}

MEDIA=$1 #the image from the command line  
TWEET=$2 #see if it was supplied on the command line
echo "Sending ${1} with message '$2' to Twitpic..."
if [ "${TWEET}" = "-v" -o "${MEDIA}" = "-v" ]; then 
  echo "${NAME} ${VERSION}" && exit; 
fi
check_for_deps
if [ -z "${TWEET}" ]; then getinput; fi #if it wasn't, prompt for it
shrink_url #shrink any url
check_length #make sure it's less than 140 characters
submit_tweet #submit it since we got past the check
if [ "$?" == 0 ]; then notify_user success && exit 0; 
else notify_user fail && exit 1; fi
